<template>
  <div class="tab-swipe">
    <van-tabs v-model="active" @click='onTabClick' class="tab-swipe-tabs" :swipe-threshold='swipeThreshold'>
      <van-tab v-for="(tab, index) of tabs" :title="tab.title" :key="index"></van-tab>
    </van-tabs>
    <div class="tab-swipe-content">
      <van-swipe :loop="false" @change="onSwipeChange" :show-indicators='false' ref="swipe" class="swipe">
        <van-swipe-item v-for="(item, index) of swipeItems" :key="index">
          <scroll pullUpLoad @pullingUp='pullingUp' :data='swipeItems[active]'>
            <slot :data='item' :active='active' v-show="item" />
          </scroll>
          <van-loading type="spinner" color='red' class="loading" v-show="loadding"/>
        </van-swipe-item>
      </van-swipe>
    </div>
  </div>
</template>
<script>
import Scroll from 'base/scroll'

export default {
  components: {
    Scroll
  },
  props: {
    tabs: {
      type: Array,
      default() {
        return []
      }
    },
    remoteMethod: {
      type: Function,
      required: true
    },
    swipeThreshold: {
      type: Number,
      default: 4
    }
  },
  data() {
    return {
      active: 0,
      swipeItems: [],
      loadActive: {},
      loadComplete: {},
      loadding: true,
      pageInfo: {}
    }
  },
  mounted() {
    this.init()
  },
  computed: {
    isLoadComplete() {
      return this.loadActive[this.active]
    },
    swipe() {
      return this.$refs.swipe
    }
  },
  methods: {
    init() {
      this.tabs.forEach(() => this.swipeItems.push([]))
      this.getSwipeData()
    },
    getSwipeData() {
      if (!this.isLoadComplete) {
        this.loadding = true
        this.getData()
      }
    },
    onTabClick(index) {
      this.emitEvent(index)
      this.swipe.swipeTo(index)
    },
    onSwipeChange(index) {
      this.active = index
      this.emitEvent(index)
      this.getSwipeData()
    },
    emitEvent(index) {
      this.$emit('onChange', index)
    },
    goTo(index) {
      this.active = index
      this.swipe.swipeTo(index)
    },
    recordPageInfo() {
      let pageInfo = this.pageInfo[this.active]
      if (pageInfo !== undefined) {
        pageInfo.offset = pageInfo.offset + 1
      } else {
        this.pageInfo[this.active] = { offset: 0 }
      }
    },
    getData() {
      return new Promise((resolve) => {
        this.recordPageInfo()

        if (this.loadComplete[this.active]) {
          resolve()
          return
        }

        const result = this.remoteMethod({
          ...this.tabs[this.active],
          offset: this.pageInfo[this.active].offset
        })
        if (result instanceof Promise) {
          const _this = this

          result.then(res => {
            let activeList = _this.swipeItems[_this.active]
            if (activeList) {
              if (res.length === 0) {
                _this.loadComplete[_this.active] = true
              }
              res = activeList.concat(res)
              _this.$set(_this.swipeItems, _this.active, res)
              _this.$set(_this.loadActive, _this.active, true)
            }
            _this.loadding = false
            this.$forceUpdate()
            resolve()
          })
        }
      })
    },
    pullingUp(finish) {
      this.getData().finally(() => finish())
    },
  }
}
</script>
<style lang="less" scoped>
.tab-swipe{
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  .tab-swipe-content{
    flex: auto;
    overflow: hidden;
    height: 0;
    padding-top: 1px;
    .swipe{
      height: 100%;
    }
  }
}
.loading{
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translateX(-50%) translateY(-50%);
}
</style>